import copy
import math
import os
import time
import tkinter as tk
from tkinter import filedialog as tf
from tkinter.messagebox import showinfo

import numpy as np
from PIL import Image, ImageGrab
import mazeGenerator


# 绘制地图单元格
def draw_cell(canvas1, row, col, color="#F2F2F2"):
    x0, y0 = col * cell_width, row * cell_width
    x1, y1 = x0 + cell_width, y0 + cell_width
    canvas1.create_rectangle(x0, y0, x1, y1, fill=color,
                             outline=color, width=0)


# 绘制地图路径
def draw_path(canvas1, matrix, row, col, color, line_color):
    # 行
    if col + 1 < cols and matrix[row][col - 1] >= 1 and matrix[row][col + 1] >= 1:
        x0, y0 = col * cell_width, row * cell_width + 2 * cell_width / 5
        x1, y1 = x0 + cell_width, y0 + cell_width / 5
    # 列
    elif row + 1 < rows and matrix[row - 1][col] >= 1 and matrix[row + 1][col] >= 1:
        x0, y0 = col * cell_width + 2 * cell_width / 5, row * cell_width
        x1, y1 = x0 + cell_width / 5, y0 + cell_width
    # 左上角
    elif col + 1 < cols and row + 1 < rows \
            and matrix[row][col + 1] >= 1 and matrix[row + 1][col] >= 1:
        x0 = col * cell_width + 2 * cell_width / 5
        y0 = row * cell_width + 2 * cell_width / 5
        x1, y1 = x0 + 3 * cell_width / 5, y0 + cell_width / 5
        canvas1.create_rectangle(x0, y0, x1, y1, fill=color,
                                 outline=line_color, width=0)
        x0 = col * cell_width + 2 * cell_width / 5
        y0 = row * cell_width + 2 * cell_width / 5
        x1, y1 = x0 + cell_width / 5, y0 + 3 * cell_width / 5
    # 右上角
    elif row + 1 < rows and matrix[row][col - 1] >= 1 and matrix[row + 1][col] >= 1:
        x0, y0 = col * cell_width, row * cell_width + 2 * cell_width / 5
        x1, y1 = x0 + 3 * cell_width / 5, y0 + cell_width / 5
        canvas1.create_rectangle(x0, y0, x1, y1, fill=color,
                                 outline=line_color, width=0)
        x0 = col * cell_width + 2 * cell_width / 5
        y0 = row * cell_width + 2 * cell_width / 5
        x1, y1 = x0 + cell_width / 5, y0 + 3 * cell_width / 5
    # 左下角
    elif col + 1 < cols and matrix[row - 1][col] >= 1 and matrix[row][col + 1] >= 1:
        x0, y0 = col * cell_width + 2 * cell_width / 5, row * cell_width
        x1, y1 = x0 + cell_width / 5, y0 + 3 * cell_width / 5
        canvas1.create_rectangle(x0, y0, x1, y1, fill=color,
                                 outline=line_color, width=0)
        x0 = col * cell_width + 2 * cell_width / 5
        y0 = row * cell_width + 2 * cell_width / 5
        x1, y1 = x0 + 3 * cell_width / 5, y0 + cell_width / 5
    # 右下角
    elif matrix[row - 1][col] >= 1 and matrix[row][col - 1] >= 1:
        x0, y0 = col * cell_width, row * cell_width + 2 * cell_width / 5
        x1, y1 = x0 + 3 * cell_width / 5, y0 + cell_width / 5
        canvas1.create_rectangle(x0, y0, x1, y1, fill=color,
                                 outline=line_color, width=0)
        x0, y0 = col * cell_width + 2 * cell_width / 5, row * cell_width
        x1, y1 = x0 + cell_width / 5, y0 + 3 * cell_width / 5
    else:
        x0 = col * cell_width + 2 * cell_width / 5
        y0 = row * cell_width + 2 * cell_width / 5
        x1, y1 = x0 + cell_width / 5, y0 + cell_width / 5

    canvas1.create_rectangle(x0, y0, x1, y1, fill=color,
                             outline=line_color, width=0)


# 绘制地图
def draw_maze(canvas1, matrix, path, moves):
    """
    根据matrix中每个位置的值绘图：
    -1: 墙壁
    0: 空白
    1: 参考路径
    2: 移动过的位置
    """
    canvas1.delete("all")
    matrix = copy.copy(matrix)
    for ph in path:
        matrix[ph[0]][ph[1]] = 1
    for move in moves:
        matrix[move[0]][move[1]] = 2
    for row in range(rows):
        for col in range(cols):
            if matrix[row][col] == 0:
                draw_cell(canvas1, row, col)
            elif matrix[row][col] == -1:
                draw_cell(canvas1, row, col, '#525288')
            elif matrix[row][col] == 1:
                draw_cell(canvas1, row, col)
                draw_path(canvas1, matrix, row, col, '#bc84a8', '#bc84a8')
            elif matrix[row][col] == 2:
                draw_cell(canvas1, row, col)
                draw_path(canvas1, matrix, row, col, '#ee3f4d', '#ee3f4d')

    windows.title("Maze Level-{} Steps-{}".format(level, click_counter))
    set_label_text()


# 更新地图
def update_maze(canvas1, matrix, path, moves):
    windows.title("Maze Level-{} Steps-{}".format(level, click_counter))
    canvas1.delete("all")
    matrix = copy.copy(matrix)
    for ph in path:
        matrix[ph[0]][ph[1]] = 1
    for move in moves:
        matrix[move[0]][move[1]] = 2

    row, col = movement_list[-1]
    colors = ['#525288', '#F2F2F2', '#525288', '#F2F2F2',
              '#525288', '#F2F2F2', '#525288', '#F2F2F2']
    if map_mode > 0:
        colors = ['#232323', '#242424', '#2a2a32', '#424242',
                  '#434368', '#b4b4b4', '#525288', '#F2F2F2']

    for r in range(rows):
        for c in range(cols):
            distance = (row - r) * (row - r) + (col - c) * (col - c)
            if distance >= 100:
                color = colors[0:2]
            elif distance >= 60:
                color = colors[2:4]
            elif distance >= 30:
                color = colors[4:6]
            else:
                color = colors[6:8]

            if matrix[r][c] == 0:
                draw_cell(canvas1, r, c, color[1])
            elif matrix[r][c] == -1:
                draw_cell(canvas1, r, c, color[0])
            elif matrix[r][c] == 1:
                draw_cell(canvas1, r, c, color[1])
                draw_path(canvas1, matrix, r, c, '#bc84a8', '#bc84a8')
            elif matrix[r][c] == 2:
                draw_cell(canvas1, r, c, color[1])
                draw_path(canvas1, matrix, r, c, '#ee3f4d', '#ee3f4d')
    set_label_text()


# 查看范围
def check_reach():
    global next_maze_flag
    if movement_list[-1] == maze.destination:
        print("Congratulations! You've managed to get out of the maze! "
              "Steps to used: {}".format(click_counter))
        save_logs(logs_path, set_log_data())
        x0, y0 = cols * cell_width / 2 - 200, 30
        x1, y1 = x0 + 400, y0 + 40
        canvas.create_rectangle(x0, y0, x1, y1, fill='#F2F2F2',
                                outline='#525288', width=3)
        canvas.create_text(cols * cell_width / 2, y0 + 20,
                           text="Congratulations!"
                                " You reach the goal! Back steps: {}".format(back_counter),
                           fill="#525288")
        next_maze_flag = True


# 绘制历史记录
def draw_result():
    # 判断日志文件是否存在，不存在则弹出警告
    if not os.path.exists(logs_path):
        showinfo(title='Warning!!!', message='当前没有任何历史数据!')
        return

    # 读取日志文件内容到text变量
    with open(logs_path, encoding="utf-8") as file:
        text = file.read()
    # 新建弹出窗口并展示text内容
    root = tk.Tk()
    root.title("历史记录")
    root.geometry("800x600+600+100")
    label1 = tk.Label(root, text=text, bd=1, anchor='w')
    label1.pack(side="top", fill='x')

    root.mainloop()


# 保存记录
def save_logs(path, text):
    with open(path, 'a+') as file:
        file.write(text)
        file.close()


# 移动_更新_处理程序
def movement_update_handler(event):
    global movement_list
    global click_counter, back_counter

    cur_pos = movement_list[-1]
    ops = {'Left': [0, -1], 'Right': [0, 1], 'Up': [-1, 0], 'Down': [1, 0],
           'a': [0, -1], 'd': [0, 1], 'w': [-1, 0], 's': [1, 0],
           'A': [0, -1], 'D': [0, 1], 'W': [-1, 0], 'S': [1, 0]}
    p1 = cur_pos[0] + ops[event.keysym][0]
    q1 = cur_pos[1] + ops[event.keysym][1]
    if len(movement_list) > 1 and [p1, q1] == movement_list[-2]:
        click_counter += 1
        back_counter += 1
        movement_list.pop()
        if auto_mode:
            while True:
                cur_pos = movement_list[-1]
                counter = 0
                for d in [[0, 1], [0, -1], [1, 0], [-1, 0]]:
                    p1, q1 = cur_pos[0] + d[0], cur_pos[1] + d[1]
                    if q1 >= 0 and maze.matrix[p1][q1] == 0:
                        counter += 1
                if counter != 2:
                    break
                movement_list.pop()

    elif p1 < maze.height and q1 < maze.width and maze.matrix[p1][q1] == 0:
        click_counter += 1
        if auto_mode:
            while True:
                movement_list.append([p1, q1])
                temp_list = []
                for lt in [[0, 1], [0, -1], [1, 0], [-1, 0]]:
                    p2, q2 = p1 + lt[0], q1 + lt[1]
                    if q2 < maze.width and maze.matrix[p2][q2] == 0 \
                            and [p2, q2] != cur_pos:
                        temp_list.append([p2, q2])
                if len(temp_list) != 1:
                    break
                cur_pos = [p1, q1]
                p1, q1 = temp_list[0]
        else:
            movement_list.append([p1, q1])

    maze.path = []
    update_maze(canvas, maze.matrix, maze.path, movement_list)
    check_reach()


# 下一层次
def next_level():
    global click_counter, total_counter, back_counter
    global next_maze_flag
    global level
    global time1

    next_maze_flag = False
    time1 = int(time.time())
    level, total_counter, click_counter, back_counter = \
        level + 1, total_counter + click_counter, 0, 0
    generate_matrix()


# 事件处理程序
def event_handler(event):
    # 判断地图状态以确定是否进入下一层
    if next_maze_flag:
        next_level()
    # 判断是否属于移动按键以确定是否调用移动更新处理程序
    elif event.keysym in ['Left', 'Right', 'Up', 'Down',
                          'w', 'a', 's', 'd',
                          'W', 'A', 'S', 'D']:
        movement_update_handler(event)
    # 判断是否是相应的快捷键以确定调用相应处理函数
    elif event.keysym == "F1":
        open_map()
    elif event.keysym == "F2":
        save_map()
    elif event.keysym == "F3":
        windows.quit()
    elif event.keysym == "F4":
        back_to_start_point()
    elif event.keysym == "F5":
        generate_matrix()
    elif event.keysym == "F6":
        manual()
    elif event.keysym == "F7":
        developer()
    elif event.keysym == "F8":
        save_answer_map()
    elif event.keysym == "F9":
        draw_result()


# 绘制答案路径
def paint_answer_path(event):
    global click_counter

    # 获取鼠标点击的坐标值转换到迷宫相应坐标位置
    x = math.floor((event.y - 1) / cell_width)
    y = math.floor((event.x - 1) / cell_width)
    # 判断点击处是否合法
    if maze.matrix[x][y] == 0:
        # 调用dfs方法寻找路径
        maze.find_path_dfs([x, y])
        click_counter += 10
        # 更新地图
        update_maze(canvas, maze.matrix, maze.path, movement_list)


# 重置回答路径
def reset_answer_path(event):
    # 获取鼠标点击的坐标值转换到迷宫相应坐标位置
    x = math.floor((event.y - 1) / cell_width)
    y = math.floor((event.x - 1) / cell_width)
    if maze.matrix[x][y] == 0:
        maze.path = []
        update_maze(canvas, maze.matrix, maze.path, movement_list)


# 生成矩阵
def generate_matrix():
    global movement_list
    global map_generate_mode
    global click_counter, back_counter

    if map_size_mode == -1:
        map_generate_mode = 0

    click_counter, back_counter = 0, 0
    movement_list = [maze.start]
    maze.generate_matrix(map_generate_mode, None)
    draw_maze(canvas, maze.matrix, maze.path, movement_list)


# 套用算法0(kruskal)
def set_algo_0():
    global map_generate_mode

    map_generate_mode = 0
    generate_matrix()


# 套用算法1(dfs深度优先)
def set_algo_1():
    global map_generate_mode

    map_generate_mode = 1
    generate_matrix()


# 套用算法2(prim)
def set_algo_2():
    global map_generate_mode

    map_generate_mode = 2
    generate_matrix()


# 套用算法3(split分割法)
def set_algo_3():
    global map_generate_mode

    map_generate_mode = 3
    generate_matrix()


# 设置地图模式0
def set_mode_0():
    global map_mode
    map_mode = 0


# 打开地图
def open_map():
    global map_generate_mode

    '''
    调用tkinter库对文件处理的askopenfilename方法，
    以弹出打开的地图文件窗口,并返回文件路径给image_path变量
    '''
    image_path = tf.askopenfilename(
        title='打开地图文件', filetypes=[('png', '*.png'), ('All Files', '*')])

    # 判断文件存在则读取地图文件并转换为游戏画面
    if image_path:
        image = Image.open(image_path)
        matrix = np.asarray(image) / -255
        # 打开地图时生成地图模式为-1
        map_generate_mode = -1
        # 根据读取的文件设置地图大小
        _set_size(len(matrix[0]), len(matrix), -1, matrix)


# 保存原地图
def save_map():
    path = "../maze_maps/maze_maps.in/"
    if not os.path.exists(path):
        os.makedirs(path)
    # imgs_len用来读取path路径下文件个数用以后面保存map定义名称
    imgs_len = len(os.listdir(path))
    '''
    图像格式转换: .convert('L')
    模式“L”为灰色图像，它的每个像素用8个bit表示，
    0表示黑，255表示白，其他数字表示不同的灰度。
    在PIL中，从模式“RGB”转换为“L”模式是按照下面的公式转换的：
    L = R * 299/1000 + G * 587/1000+ B * 114/1000
    '''
    image = Image.fromarray(-255 * maze.matrix).convert('L')
    image.save("{}map_{}.png".format(path, str(imgs_len), 'PNG'))
    # 展示保存成功提示
    showinfo(title='亲爱的用户', message='当前地图已保存在{}'.format(path))
    image.show()


# 彩色截图保存
def save_answer_map():
    path = "../maze_maps/maze_maps.out/"
    if not os.path.exists(path):
        os.makedirs(path)
    # imgs_len用来读取path路径下文件个数用以后面保存map定义名称
    imgs_len = len(os.listdir(path))
    img = ImageGrab.grab()
    img.save("{}answer_map_{}.png".format(path, str(imgs_len), 'PNG'))
    showinfo(title='亲爱的用户', message='当前答案地图已保存在{}'.format(path))
    img.show()


# 设置尺寸
def _set_size(width1, height1, mode, matrix=None):
    global map_size_mode
    global rows, cols
    global movement_list
    global click_counter, back_counter

    # 重置数据,获取当前地图尺寸模式，更新画布宽度和高度
    click_counter, back_counter = 0, 0
    map_size_mode = mode
    movement_list = [maze.start]
    rows, cols = height1, width1
    canvas['width'] = width1 * cell_width
    canvas['height'] = height1 * cell_width

    # 根据实际情况重设迷宫矩阵尺寸
    if mode == -1:
        maze.resize_matrix(width1, height1, -1, matrix)
    else:
        maze.resize_matrix(width1, height1, map_generate_mode, matrix)

    # 重绘地图
    draw_maze(canvas, maze.matrix, maze.path, movement_list)


# 内置尺寸1:33*33
def set_size_33x33():
    _set_size(33, 33, 0)


# 内置尺寸2:39*39
def set_size_39x39():
    _set_size(39, 39, 1)


# 内置尺寸3:31*69
def set_size_31x69():
    _set_size(69, 31, 2)


# 自定义大小
def set_size_Custom():
    # 添加新标签及文本输入框以接收用户自定义输入的数据
    l1 = tk.Label(windows, text='请输入rows(奇数):')
    l2 = tk.Label(windows, text='请输入cols(奇数):')
    l3 = tk.Label(windows, text='请输入单元格大小(偶数):')
    t1 = tk.StringVar()
    t2 = tk.StringVar()
    t3 = tk.StringVar()
    t1.set('')
    t2.set('')
    t3.set('')
    l1.pack()
    tk.Entry(windows, textvariable=t1).pack()
    l2.pack()
    tk.Entry(windows, textvariable=t2).pack()
    l3.pack()
    tk.Entry(windows, textvariable=t3).pack()

    # 获取当前文本框内数据,根据自定义情况进行尺寸设定
    def change_size():
        global rows
        global cols
        global cell_width

        if len(t1.get()) > 0:
            rows = int(t1.get())
        if len(t2.get()) > 0:
            cols = int(t2.get())
        if len(t3.get()) > 0:
            cell_width = int(t3.get())
        _set_size(cols, rows, 3)

    # 添加确定按钮以调用自定义信息获取函数change_size()
    tk.Button(windows, text='确定', command=change_size).pack()
    windows.mainloop()


# 回到起点
def back_to_start_point():
    global movement_list
    global click_counter

    # 重置数据,重绘地图
    click_counter = 0
    movement_list = [maze.start]
    draw_maze(canvas, maze.matrix, maze.path, movement_list)


# 设置_部分寻路开启
def set_auto_on():
    global auto_mode
    auto_mode = True


# 设置_部分寻路关闭
def set_auto_off():
    global auto_mode
    auto_mode = False


# 开发者信息
def developer():
    showinfo(title='开发者信息', message='当前版本：v 1.0.1\n'
                                    '开发时间：2020年元旦\n开发者：WXShuai')


# 操作说明
def manual():
    showinfo(title='操作说明', message='控制移动：方向键(w/up; s/down; a/left; d/right)\n'
                                   '查看提示：鼠标单击地图中空白处即可查看从起点到点击处的路径(查看一次提示增加10步)\n'
                                   '进入下一关：到达终点后按任意键进入下一关\n'
                                   '快捷键:读取地图/F1;保存原地图/F2;保存彩色地图/F8;退出/F3;回到起点/F4;\n'
                                   '刷新地图/F5;查看日志/F9;操作说明/F6;开发者信息/F7\n'
                                   '注意:彩色地图不可被重新读取!!!')


# 设置标签文字
def set_label_text():
    message = " Mode: {}   Map size: {}   Algorithm: {}   Total steps: {}   Back steps: {}   Time: {}s" \
        .format("Simple" if map_mode == 0 else 'Roguelike',
                ['33x33', '39x39', '31x69', '{}x{}'.format(rows, cols)][map_size_mode]
                if map_size_mode >= 0 else "{}x{} "
                .format(cols, rows), ['Kruskal', 'DFS', 'Prim', 'Recursive Split']
                [map_generate_mode] if map_generate_mode >= 0 else 'Unknown',
                click_counter + total_counter, back_counter, int(time.time() - time0))
    label["text"] = message

    return message


# 设置_日志_数据
def set_log_data():
    count = 0
    f = open(logs_path, "r")
    for _ in f.readlines():
        count += 1
    f.close()

    return "({}) [{}]Mode:{},Map-size:{},Algorithm:{},Level:{},Steps:{},Back_steps:{}," \
           "Time-cost:{}\n".format(count + 1, (time.strftime("%Y-%m-%d %H:%M:%S"),
                                               time.localtime(int(time.time()))),
                                   "Simple" if map_mode == 0 else 'Roguelike',
                                   ['33x33', '39x39', '31x69', '{}x{}'.format(rows, cols)][map_size_mode]
                                   if map_size_mode >= 0 else "{}x{}"
                                   .format(cols, rows), ['Kruskal', 'DFS', 'Prim', 'Recursive Split']
                                   [map_generate_mode] if map_generate_mode >= 0 else 'Unknown',
                                   level, click_counter, back_counter, int(time.time() - time1))


# 主函数
if __name__ == '__main__':
    # 基础参数
    logs_path = '../maze_logs/maze_game.log'
    maps_save_path = '../maze_maps/maze_maps.in/'
    answers_save_path = '../maze_maps/maze_maps.out/'
    cell_width = 16
    rows = 31
    cols = 69
    height = cell_width * rows
    width = cell_width * cols
    level = 1
    click_counter, total_counter, back_counter = 0, 0, 0
    next_maze_flag = False

    # 地图生成算法：(默认)0-kruskal，1-dfs，2-prim，3-split
    map_generate_mode = 0
    # 游戏模式：(默认)0-普通模式
    map_mode = 0
    # 地图大小：0-33x33, 1-39x39, (默认)2-69x31, 3-自定义
    map_size_mode = 2
    # 自动前进模式，默认开
    auto_mode = True

    # 创建主窗口
    windows = tk.Tk()
    windows.title("MyMaze!!!")
    windows.resizable(0, 0)
    time0 = int(time.time())
    time1 = time0

    # 创建菜单栏
    menubar = tk.Menu(windows)

    # 文件菜单选项
    filemenu = tk.Menu(menubar, tearoff=0)
    menubar.add_cascade(label='开始菜单', menu=filemenu)
    filemenu.add_command(label='读取地图', command=open_map, accelerator='F1')
    filemenu.add_command(label='保存原地图', command=save_map, accelerator='F2')
    filemenu.add_command(label='保存彩色地图', command=save_answer_map, accelerator='F8')
    filemenu.add_separator()  # 分割线
    filemenu.add_command(label='退出游戏', command=windows.quit, accelerator='F3')

    # 设置菜单选项
    editmenu = tk.Menu(menubar, tearoff=0)
    menubar.add_cascade(label='游戏设置', menu=editmenu)
    editmenu.add_command(label='回到起点', command=back_to_start_point, accelerator='F4')
    editmenu.add_command(label='更换地图', command=generate_matrix, accelerator='F5')

    # 尺寸设置菜单选项
    sizemenu = tk.Menu(editmenu, tearoff=0)
    editmenu.add_cascade(label='尺寸设置', menu=sizemenu)
    sizemenu.add_command(label='33x33', command=set_size_33x33)
    sizemenu.add_command(label='39x39', command=set_size_39x39)
    sizemenu.add_command(label='31x69', command=set_size_31x69)
    sizemenu.add_command(label='自定义大小', command=set_size_Custom)

    # 前进方式菜单选项
    automenu = tk.Menu(editmenu, tearoff=0)
    editmenu.add_cascade(label='前进方式', menu=automenu)
    automenu.add_command(label='部分寻路开', command=set_auto_on)
    automenu.add_command(label='部分寻路关', command=set_auto_off)

    # 游戏模式菜单选项
    modemenu = tk.Menu(editmenu, tearoff=0)
    editmenu.add_cascade(label='游戏模式', menu=modemenu)
    modemenu.add_command(label='普通模式', command=set_mode_0)

    # 迷宫生成算法菜单选项
    algomenu = tk.Menu(editmenu, tearoff=0)
    editmenu.add_cascade(label='生成算法', menu=algomenu)
    algomenu.add_command(label='Kruskal最小生成树算法', command=set_algo_0)
    algomenu.add_command(label='dfs深度优先算法', command=set_algo_1)
    algomenu.add_command(label='prim最小生成树算法', command=set_algo_2)
    algomenu.add_command(label='递归分割算法', command=set_algo_3)

    # 历史记录菜单选项
    scoremenu = tk.Menu(menubar, tearoff=0)
    menubar.add_cascade(label='历史记录', menu=scoremenu)
    scoremenu.add_command(label='日志文件', command=draw_result, accelerator='F9')

    # 帮助菜单选项
    helpmenu = tk.Menu(menubar, tearoff=0)
    menubar.add_cascade(label='游戏帮助', menu=helpmenu)
    helpmenu.add_command(label='操作说明', command=manual, accelerator='F6')
    helpmenu.add_command(label='开发者信息', command=developer, accelerator='F7')

    # 为窗口添加主菜单
    windows.config(menu=menubar)

    # end_创建菜单栏

    # 创建状态栏

    # 标签
    label = tk.Label(windows, text="My maze game!!!", bd=1, anchor='w')
    label.pack(side="bottom", fill='x')
    set_label_text()

    # 画布
    canvas = tk.Canvas(windows, background="#F2F2F2", width=width, height=height)
    canvas.pack()

    # 迷宫
    maze = mazeGenerator.Maze_(cols, rows)
    movement_list = [maze.start]
    generate_matrix()

    # 按键及事件处理
    canvas.bind("<Button-1>", paint_answer_path)
    canvas.bind("<Button-3>", reset_answer_path)
    canvas.bind_all("<KeyPress>", event_handler)

    windows.mainloop()

    # end_创建状态栏
